home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / gnushogi.lha / gnushogi-1.1 / src / main.c < prev    next >
C/C++ Source or Header  |  1993-04-18  |  14KB  |  620 lines

  1. /*
  2.  * main.c - C source for GNU SHOGI based on GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback (GNU Chess)
  5.  * Copyright (c) 1992 Free Software Foundation 
  6.  * Copyright (c) 1993 Matthias Mutz (GNU Shogi)
  7.  *
  8.  * This file is part of GNU SHOGI.
  9.  *
  10.  * GNU Shogi is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 1, or (at your option)
  13.  * any later version.
  14.  *
  15.  * GNU Shogi is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with GNU Shogi; see the file COPYING.  If not, write to
  22.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  */
  24.  
  25.  
  26. #if !defined NO_MAIN
  27.  
  28. #include "version.h"
  29. #include "gnushogi.h"
  30.  
  31. #endif
  32.  
  33. #include <signal.h>
  34.  
  35. #if defined THINK_C
  36. #include <console.h>
  37. #include <time.h>
  38. #define MAKE_BOOK
  39. #endif
  40.  
  41. #if !defined K32SEGMENTS
  42. #include "main_data1.c"
  43. #include "main_data2.c"
  44. #endif
  45.  
  46.  
  47. #if defined HASGETTIMEOFDAY && defined THINK_C
  48.  
  49. #define USEC_PER_CLOCK (1000000 / CLOCKS_PER_SEC)
  50.  
  51. int gettimeofday(struct timeval *tp, void *tzp)
  52.    long clock_count = (long)clock();
  53.    tp->tv_sec = clock_count / CLOCKS_PER_SEC;
  54.    tp->tv_usec = (clock_count % CLOCKS_PER_SEC) * USEC_PER_CLOCK;
  55.    return(0);
  56. }
  57.  
  58. #endif
  59.  
  60. /*
  61.  * In a networked enviroment gnuchess might be compiled on different hosts
  62.  * with different random number generators, that is not acceptable if they
  63.  * are going to share the same transposition table.
  64.  */
  65. unsigned long int next = 1;
  66.  
  67. unsigned int
  68. urand (void)
  69. {
  70.   next *= 1103515245;
  71.   next += 12345;
  72.   return ((unsigned int) (next >> 16) & 0xFFFF);
  73. }
  74.  
  75. void
  76. gsrand (unsigned int seed)
  77. {
  78.   next = seed;
  79. }
  80.  
  81. #if ttblsz
  82. struct hashentry huge *ttable[2];
  83. unsigned int ttblsize;
  84. #endif
  85. #ifdef BINBOOK
  86. extern char *binbookfile;
  87. #endif
  88. extern char *bookfile;
  89.  
  90. unsigned long hashkey, hashbd;
  91. struct hashval hashcode[2][NO_PIECES][NO_SQUARES+(2*NO_PIECES)];
  92.  
  93. char savefile[128] = "";
  94. char listfile[128] = "";
  95.  
  96. #if defined HISTORY
  97. unsigned short *history;
  98. #endif
  99.  
  100. short rpthash[2][256];
  101. short TrPnt[MAXDEPTH];
  102. small_short PieceList[2][NO_SQUARES];
  103. small_short PawnCnt[2][NO_COLS];
  104. small_short Captured[2][NO_PIECES];
  105. small_short Mvboard[NO_SQUARES];
  106. short svalue[NO_SQUARES];
  107. struct flags flag;
  108.  
  109. short opponent, computer, WAwindow, WBwindow, BAwindow, BBwindow, dither,
  110.   INCscore;
  111. long ResponseTime, ExtraTime, MaxResponseTime, et, et0, time0, ft;
  112. long GenCnt, NodeCnt, ETnodes, EvalNodes, HashCnt, HashAdd, FHashCnt, FHashAdd,
  113.   HashCol, THashCol, filesz, hashmask, hashbase;
  114. long replus, reminus;
  115. short HashDepth = HASHDEPTH, HashMoveLimit = HASHMOVELIMIT;
  116. short player, xwndw;
  117. /*unsigned*/ short rehash; /* -1 is used as a flag --tpm */
  118. short Sdepth, Game50, MaxSearchDepth;
  119. short GameCnt = 0;
  120. short contempt;
  121. int Book;
  122. struct TimeControlRec TimeControl;
  123. int TCadd = 0;
  124. short TCflag, TCmoves, TCminutes, TCseconds, OperatorTime;
  125. short XCmoves[3], XCminutes[3], XCseconds[3], XC, XCmore;
  126. const short otherside[3] =
  127. {white, black, neutral};
  128. unsigned short hint;
  129. short int TOflag;        /* force search re-init if we backup search */
  130.  
  131. unsigned short killr0[MAXDEPTH], killr1[MAXDEPTH];
  132. unsigned short killr2[MAXDEPTH], killr3[MAXDEPTH];
  133. unsigned short PV, SwagHt, Swag0, Swag1, Swag2, Swag3, Swag4, sidebit;
  134.  
  135. const small_short sweep[NO_PIECES] =
  136. {false, false, true,  false, false, false, true, true,
  137.         false, false, false, false, true,  true,  false };
  138. small_short HasPiece[2][NO_PIECES]; 
  139. const short kingP[3] =
  140. {4, 76, 0};
  141. const short value[NO_PIECES] =
  142. {0, valueP,  valueL,  valueN,  valueS,  valueG,  valueB,  valueR,
  143.     valuePp, valueLp, valueNp, valueSp, valueBp, valueRp, valueK}; 
  144. const small_short relative_value[NO_PIECES] =
  145. {0, 1,       3,       4,       7,       9,       10,      12, 
  146.     2,       5,       6,       8,       11,      13,      14};
  147. const long control[NO_PIECES] =
  148. {0, ctlP, ctlL, ctlN, ctlS, ctlG, ctlB, ctlR,
  149.     ctlPp, ctlLp, ctlNp, ctlSp, ctlBp, ctlRp, ctlK };
  150.  
  151. short stage, stage2;
  152.  
  153. FILE *hashfile;
  154.  
  155. unsigned int starttime;
  156. short int ahead = true, hash = true;
  157.  
  158.  
  159. #if defined XSHOGI
  160. void
  161. TerminateChess (int sig)
  162. {
  163.   ExitChess ();
  164. }
  165.  
  166. #endif
  167.  
  168.  
  169.  
  170. int timeopp[MINGAMEIN], timecomp[MINGAMEIN];
  171. int compptr, oppptr;
  172. inline void
  173. TimeCalc ()
  174. {
  175. /* adjust number of moves remaining in gamein games */
  176.   int increment = 0;
  177.   int topsum = 0;
  178.   int tcompsum = 0;
  179.   int me,him;
  180.   int i;
  181. /* dont do anything til you have enough numbers */
  182.   if (GameCnt < (MINGAMEIN * 2)) return;
  183. /* calculate average time in sec for last MINGAMEIN moves */
  184.   for (i = 0; i < MINGAMEIN; i++)
  185.     {
  186.       tcompsum += timecomp[i];
  187.       topsum += timeopp[i];
  188.     }
  189.   topsum /= (100 * MINGAMEIN);
  190.   tcompsum /= (100 * MINGAMEIN);
  191. /* if I have less time than opponent add another move */
  192.     me = TimeControl.clock[computer]/100; 
  193.     him = TimeControl.clock[opponent]/100;
  194.     if(me < him) increment += 2;
  195.     if((him - me) > 60 || (me<him && me < 120))increment++;
  196. /* if I am losing more time with each move add another */
  197.   /*if ( !((me - him) > 60) && tcompsum > topsum) increment++;*/
  198.   if ( tcompsum > topsum) increment +=2;
  199. /* but dont let moves go below MINMOVES */
  200.   else if (TimeControl.moves[computer] < MINMOVES && !increment) increment++;
  201. /* if I am doing really well use more time per move */
  202.   else if (me > him && tcompsum < topsum) increment = -1;
  203.   TimeControl.moves[computer] += increment;
  204. }
  205.  
  206.  
  207.  
  208.  
  209. #ifdef DEBUG_INITS
  210.  
  211. /* print all possible moves for all pieces from all squares */
  212.  
  213. void DebugInits ()
  214. {                    
  215.    register short u, sq;
  216.    register unsigned char *ppos, *pdir;
  217.    char s[10];
  218.    short piece, ptyp;
  219.  
  220.    for ( piece = 0; piece < NO_PIECES; piece++ ) {
  221.      printf("move list for piece %i\n",piece);
  222.      for ( sq = 0; sq < NO_SQUARES; sq++ ) {
  223.        printf("  from square %i to ",sq);
  224.        ptyp = ptype[black][piece];
  225.        ppos = (*nextpos[ptyp])[sq];
  226.        u = ppos[sq]; 
  227.        do {
  228.           printf("%i",u);
  229.           u = ppos[u];
  230.           if (u != sq) printf(", ");
  231.        } while (u != sq); 
  232.        printf("\n");
  233.      };
  234.      /* pdir = (*nextdir[ptyp])[sq]; */
  235.      printf("\n");
  236.      scanf("%s",s);
  237.      if ( strcmp(s,"exit") == 0 )
  238.        exit(0);
  239.    };
  240. }
  241.  
  242. #endif          
  243.  
  244.  
  245. #if !defined NO_MAIN
  246.  
  247.  
  248. /* hmm.... shouldn`t main be moved to the interface routines */
  249. int
  250. main (int argc, char **argv)
  251. {
  252.   char *xwin = 0;
  253.   char *Lang = NULL;
  254.   size_t n;
  255. #ifdef THINK_C
  256.   console_options.ncols = 100;
  257.   cshow(stdout);
  258. #endif
  259. #if defined CACHE
  260.   n = sizeof(struct etable) * (size_t)ETABLE;
  261.   if ( !(etab[0] = (etable_field *)malloc(n)) ) {
  262.     ShowMessage ("cannot allocate cache table 0\n");
  263.   }
  264.   if ( !(etab[1] = (etable_field *)malloc(n)) ) {
  265.     ShowMessage ("cannot allocate cache table 1\n");
  266.   }
  267. #endif
  268. #if defined HISTORY
  269.   if ( !(history = (unsigned short *)malloc(sizeof_history)) ) {
  270.     ShowMessage ("cannot allocate history table\n");
  271.   }
  272. #endif
  273. #if defined THINK_C
  274.   gsrand (starttime = ((unsigned int) time ((time_t *) 0)));    /* init urand */
  275. #else
  276.   gsrand (starttime = ((unsigned int) time ((long *) 0)));    /* init urand */
  277. #endif
  278. #if ttblsz
  279.   ttblsize = ttblsz;
  280.   rehash = -1;
  281. #endif /* ttblsz */
  282.   if (argc > 2)
  283.     {
  284.       if (argv[1][0] == '-' && argv[1][1] == 'L')
  285.     {
  286.       Lang = argv[2];
  287.       argv += 2;
  288.       argc -= 2;
  289.     }
  290.     }
  291.   InitConst (Lang);
  292.   ColorStr[0] = CP[118];
  293.   ColorStr[1] = CP[119];
  294.   
  295. #if defined MAKE_BOOK
  296.   bookfile = BOOK;
  297.   binbookfile = BINBOOK;
  298.   booksize = 8000;
  299.   bookmaxply = 40;
  300. #endif
  301.  
  302.   while (argc > 1 && ((argv[1][0] == '-') || (argv[1][0] == '+')))
  303.     {
  304.       switch (argv[1][1])
  305.     {
  306.     case 'a':
  307.       ahead = ((argv[1][0] == '-') ? false : true);
  308.       break;
  309.     case 'b':
  310.       argv++;
  311.       argc--;
  312.       if (argc > 1)
  313.         {
  314.           bookfile = argv[1];
  315. #ifdef BINBOOK
  316.           binbookfile = NULL;
  317. #endif
  318.         }
  319.       break;
  320. #ifdef BINBOOK
  321.     case 'B':
  322.       argv++;
  323.       argc--;
  324.       if (argc > 1)
  325.         binbookfile = argv[1];
  326.       break;
  327. #endif
  328.     case 'h':
  329.       hash = ((argv[1][0] == '-') ? false : true);
  330.       break;
  331.     case 's':
  332.       argc--;
  333.       argv++;
  334.       if (argc > 1)
  335.         strcpy (savefile, argv[1]);
  336.       break; 
  337.     case 'l':
  338.       argc--;
  339.       argv++;
  340.       if (argc > 1)
  341.         strcpy (listfile, argv[1]);
  342.       break;
  343.     case 'S':
  344.       argc--;
  345.       argv++;
  346.       if(argc > 1)booksize = atoi(argv[1]);
  347.       break;
  348.     case 'P':
  349.       argc--;
  350.       argv++;
  351.       if(argc > 1)bookmaxply = atoi(argv[1]);
  352.       break;
  353.  
  354. #if ttblsz
  355.     case 'r':
  356.       if (argc > 2)
  357.         rehash = atoi (argv[2]);
  358.       argc--;
  359.       argv++;
  360.       if (rehash > MAXrehash)
  361.         rehash = MAXrehash;
  362.       break;
  363.     case 'T':
  364.       if (argc > 2)
  365.         ttblsize = atoi (argv[2]);
  366.       argc--;
  367.       argv++;
  368.       if (ttblsize > 0 && ttblsize < 24)
  369.         ttblsize = (1 << ttblsize);
  370.       else
  371.         ttblsize = ttblsz;
  372.       break;
  373. #ifdef HASHFILE
  374.     case 't':    /* create or test persistent transposition
  375.                  * table */
  376.       hashfile = fopen (HASHFILE, RWA_ACC);
  377.       if (hashfile)
  378.         {
  379.           fseek (hashfile, 0L, SEEK_END);
  380.           filesz = (ftell (hashfile) / sizeof (struct fileentry)) - 1;
  381.         }
  382.       if (hashfile != NULL)
  383.         {
  384.           long i, j;
  385.           int nr[MAXDEPTH];
  386.           struct fileentry n;
  387.  
  388.           printf (CP[49]);
  389.           for (i = 0; i < MAXDEPTH; i++)
  390.         nr[i] = 0;
  391.           fseek (hashfile, 0L, SEEK_END);
  392.           i = ftell (hashfile) / sizeof (struct fileentry);
  393.           fseek (hashfile, 0L, SEEK_SET);
  394.           for (j = 0; j < i + 1; j++)
  395.         {
  396.           fread (&n, sizeof (struct fileentry), 1, hashfile);
  397. if(n.depth >MAXDEPTH) {printf("ERROR\n");exit(1);}
  398.           if (n.depth)
  399.             {
  400.               nr[n.depth]++;
  401.               nr[0]++;
  402.             }
  403.         }
  404.           printf (CP[109],
  405.               nr[0], i);
  406.           for (j = 1; j < MAXDEPTH; j++)
  407.         printf ("%d ", nr[j]);
  408.           printf ("\n");
  409.         }
  410.       return 0;
  411.     case 'c':        /* create or test persistent transposition
  412.                  * table */
  413.       if (argc > 2)
  414.         filesz = atoi (argv[2]);
  415.       if (filesz > 0 && filesz < 24)
  416.         filesz = (1 << filesz) - 1 + MAXrehash;
  417.       else
  418.         filesz = Deffilesz + MAXrehash;
  419.       if ((hashfile = fopen (HASHFILE, RWA_ACC)) == NULL)
  420.         hashfile = fopen (HASHFILE, WA_ACC);
  421.       if (hashfile != NULL)
  422.         {
  423.           long j;
  424.           struct fileentry n;
  425.  
  426.           printf (CP[66]);
  427.           n.f = n.t = 0;
  428.           n.flags = 0;
  429.           n.depth = 0;
  430.           n.sh = n.sl = 0;
  431.           for (j = 0; j < filesz + 1; j++)
  432.         fwrite (&n, sizeof (struct fileentry), 1, hashfile);
  433.           fclose (hashfile);
  434.         }
  435.       else
  436.         printf (CP[50], HASHFILE);
  437.       return (0);
  438. #endif /* HASHFILE */
  439. #endif /* ttblsz */
  440.     case 'x':
  441.       xwin = &argv[1][2];
  442.       break;
  443.     case 'v':
  444.       fprintf (stderr, CP[102], version, patchlevel);
  445.       exit (1);
  446.     default:
  447.       fprintf (stderr, CP[113]);
  448.       exit (1);
  449.     }
  450.       argv++;
  451.       argc--;
  452.     }
  453.   XC = 0;
  454.   MaxResponseTime = 0;
  455. #if defined XSHOGI
  456.   signal (SIGTERM, TerminateChess);
  457. #endif
  458. #if defined XSHOGI
  459.   TCflag = true;
  460.   TCmoves = 40;
  461.   TCminutes = 5;
  462.   TCseconds = 0;
  463.   TCadd = 0;
  464.   OperatorTime = 0;
  465. #else
  466.   TCflag = false;
  467.   OperatorTime = 0;
  468. #endif
  469.   if (argc == 2)
  470.     {
  471.       char *p;
  472.       
  473.       MaxResponseTime = 100L * strtol (argv[1], &p, 10);
  474.       if (*p == ':')
  475.     MaxResponseTime = 60L * MaxResponseTime +
  476.       100L * strtol (++p, (char **) NULL, 10);
  477.       TCflag = false;
  478.       TCmoves = 0;
  479.       TCminutes = 0;
  480.       TCseconds = 0;
  481.     }
  482.   if (argc >= 3)
  483.     {
  484.       char *p;
  485.       if (argc > 9)
  486.     {
  487.       printf ("%s\n", CP[220]);
  488.       exit (1);
  489.     }
  490.       TCmoves = atoi (argv[1]);
  491.       TCminutes = (short)strtol (argv[2], &p, 10);
  492.       if (*p == ':')
  493.     TCseconds = (short)strtol (p + 1, (char **) NULL, 10);
  494.       else
  495.     TCseconds = 0;
  496.       TCflag = true;
  497.       argc -= 3;
  498.       argv += 3;
  499.       while (argc > 1)
  500.     {
  501.       XCmoves[XC] = atoi (argv[0]);
  502.       XCminutes[XC] = (short)strtol (argv[1], &p, 10);
  503.       if (*p == ':')
  504.         XCseconds[XC] = (short)strtol (p + 1, (char **) NULL, 10);
  505.       else
  506.         XCseconds[XC] = 0;
  507.       if (XCmoves[XC] && (XCminutes[XC] || XCseconds[XC]))
  508.         XC++;
  509.       else
  510.         {
  511.           printf (CP[220]);
  512.           exit (1);
  513.         }
  514.       argc -= 2;
  515.       argv += 2;
  516.     }
  517.       if (argc)
  518.     {
  519.       printf ("%s\n", CP[220]);
  520.       exit (1);
  521.     }
  522.     }
  523.   Initialize ();
  524.   Initialize_dist ();
  525.   Initialize_moves ();
  526. #ifdef DEBUG_INITS
  527.   DebugInits ();
  528. #endif
  529.   NewGame ();
  530.  
  531.   flag.easy = ahead;
  532.   flag.hash = hash;
  533.   if (xwin)
  534.     xwndw = atoi (xwin);
  535.  
  536.   hashfile = NULL;
  537. #if ttblsz
  538. #ifdef HASHFILE
  539.   hashfile = fopen (HASHFILE, RWA_ACC);
  540.   if (hashfile)
  541.     {
  542.       fseek (hashfile, 0L, SEEK_END);
  543.       filesz = ftell (hashfile) / sizeof (struct fileentry) - 1 - MAXrehash;
  544.               hashmask = filesz>>1;
  545.           hashbase = hashmask+1;
  546.     }               
  547. #else
  548. #ifndef BAREBONES
  549. #ifdef HASHFILE
  550.   else
  551. #endif
  552.     gotoXY (3, 0);
  553.     ShowMessage (CP[98]);
  554. #endif
  555. #endif /* HASHFILE */
  556. #endif /* ttblsz */
  557.   while (!(flag.quit))
  558.     {
  559.       oppptr = (oppptr + 1) % MINGAMEIN;
  560.       if (flag.bothsides && !flag.mate)
  561.     SelectMove (opponent, 1);
  562.       else
  563.     InputCommand ();
  564.       if (opponent == white)
  565.     if (flag.gamein || TCadd)
  566.       {
  567.         TimeCalc ();
  568.       }
  569.     else if (TimeControl.moves[opponent] == 0)
  570.       {
  571.         if (XC)
  572.           if (XCmore < XC)
  573.         {
  574.           TCmoves = XCmoves[XCmore];
  575.           TCminutes = XCminutes[XCmore];
  576.           TCseconds = XCseconds[XCmore];
  577.           XCmore++;
  578.         }
  579.         SetTimeControl ();
  580.       }
  581.  
  582.       compptr = (compptr + 1) % MINGAMEIN;
  583.       if (!(flag.quit || flag.mate || flag.force))
  584.     {
  585.       SelectMove (computer, 1);
  586.       if (computer == white)
  587.         if (flag.gamein)
  588.           {
  589.         TimeCalc ();
  590.           }
  591.         else if (TimeControl.moves[computer] == 0)
  592.           {
  593.         if (XC)
  594.           if (XCmore < XC)
  595.             {
  596.               TCmoves = XCmoves[XCmore];
  597.               TCminutes = XCminutes[XCmore];
  598.               TCseconds = XCseconds[XCmore];
  599.               XCmore++;
  600.             }
  601.         SetTimeControl ();
  602.           }
  603.     }
  604.     }
  605. #if ttblsz
  606. #ifdef HASHFILE
  607.   if (hashfile)
  608.     fclose (hashfile);
  609. #endif /* HASHFILE */
  610. #endif /* ttblsz */
  611.  
  612.   ExitChess ();
  613.   return (0);
  614. }
  615.  
  616.  
  617. #endif /* NO_MAIN */
  618.  
  619.